
import * as vscode from 'vscode';
import * as Path from 'path';
import * as fs from 'fs';
import { ShellService } from '../service/ShellService';
import { Logs } from '../util/Logs';

import { AccessOptions, Client, FileInfo } from "basic-ftp";
import { LANGUAGE_DOWNLOAD_SUCCESSFUL, LANGUAGE_FILE_NOT_EXIST, LANGUAGE_FTP_OPERATION_ERROR, LANGUAGE_UPDATE_SUCCESSFUL } from '../native/StringTable';
import { IDEManager } from './IDEManager';
import { getWorkspacePath } from '../util/Workspace';
import * as os from 'os';
import { Port } from 'dockerode';

export class FTPManager {
    /**
     *  service string,port:number
     */
    private static service: FTPManager;
    private logger = Logs.logger

    private shellService: ShellService = ShellService.getService();

    private static ftpClints = new Map<string, Client>();
    public static getInstance(): FTPManager {
        if (!this.service)
            this.service = new FTPManager();
        return this.service;
    }
    private static getAddress(host:string,port?:number):string{
        return `${host}:${port??21}`
    }
    public static async connectToFTP(options:AccessOptions):Promise<boolean> {
        if(!options.host){
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ftp 地址不能为空`);
            return false;
        }
        const client = new Client();
        client.ftp.verbose = true; // 可选：启用调试信息
        const address=this.getAddress(options.host,options.port);
        if (this.ftpClints.has(address)) {
            return false;
        }
        try {
            // 连接到 FTP 服务器
            await client.access(options);
            this.ftpClints.set(address, client);
            return true;
        } catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
            return false;
        }
    }

    public static async list(ftpServer:FTPType.Server): Promise<FileInfo[] | undefined> {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            const res = await client.list() ?? [];
            return res;
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}：${error}`);
        }
    }
    public static async upload(ftpServer:FTPType.Server, localFilePath: string, remoteDirPath: string) {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            if (!fs.existsSync(localFilePath)) {
                vscode.window.showErrorMessage(`${localFilePath} ${LANGUAGE_FILE_NOT_EXIST}`);
            }
            const fileName = Path.basename(localFilePath)
            await client.uploadFrom(localFilePath, Path.join(remoteDirPath, fileName));
            vscode.window.showInformationMessage(`${LANGUAGE_UPDATE_SUCCESSFUL}: ${localFilePath}`)
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async downlaod(ftpServer:FTPType.Server, remoteFilePath: string) {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            let defaultPath=getWorkspacePath();
            if(!defaultPath){
                defaultPath=os.homedir();
            }
            const defaultFolder = vscode.Uri.file(defaultPath);
            const  localDirPath=await IDEManager.getInstance().getDirPathDailog("选择文件夹",defaultFolder);
            if(!localDirPath){
                vscode.window.showWarningMessage("未选择文件夹");
                return;
            }
            const fileName = Path.basename(remoteFilePath)
            const localFilePath=Path.join(localDirPath, fileName)
            await client.downloadTo(localDirPath, remoteFilePath);
            vscode.window.showInformationMessage(`${LANGUAGE_DOWNLOAD_SUCCESSFUL}: ${localFilePath}`)
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async pwd(ftpServer:FTPType.Server): Promise<String | undefined> {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            const pwdRes=await client.pwd();
            return pwdRes;
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async cd(ftpServer:FTPType.Server, dir: string) {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            await client.cd(dir);
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async cdup(ftpServer:FTPType.Server) {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                vscode.window.showErrorMessage(`${address} connection is closed`);
                return;
            }
            await client.cdup();
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async close(ftpServer:FTPType.Server) {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                return;
            }
            await client.close();
            this.ftpClints.delete(address);
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }

    public static async cdAndList(ftpServer:FTPType.Server, dir: string): Promise<FileInfo[] | undefined> {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                return;
            }
            await client.cd(dir);
            const res = await client.list() ?? [];
            return res;
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    public static async cdupAndList(ftpServer:FTPType.Server): Promise<FileInfo[] | undefined> {
        try {
            const address=this.getAddress(ftpServer.host,ftpServer.port);
            const client = this.ftpClints.get(address);
            if (!client || client.closed) {
                return;
            }
            await client.cdup();
            const res = await client.list() ?? [];
            return res;
        }
        catch (error) {
            vscode.window.showErrorMessage(`${LANGUAGE_FTP_OPERATION_ERROR}: ${error}`);
        }
    }
    
    
}